-
Notifications
You must be signed in to change notification settings - Fork 42
Pairing exercise: Let merchant to notify shipment of an order #31
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
| if (shipmentTotal.compareTo(orderAmount.amount) > 0) | ||
| throw ShipmentAmountExceedOrderTotalException(ShipmentAmount(shipmentTotal), orderId!!) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Order domain keeps track of the business rule where total amount of all shipments don't exceed order amount.
| */ | ||
| data class OrderAmount(val amount: BigDecimal) { | ||
| init { | ||
| require(amount.compareTo(BigDecimal.ZERO) > 0) { "Order amount must be positive" } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Order amount and also shipment amount domain objects ensure that it always receives positive value
| private fun mapToDtos(orders: List<Order>): List<OrderDto> { | ||
| return orders.stream() | ||
| .map(this::mapToDto) | ||
| .collect(Collectors.toList()) | ||
| } | ||
|
|
||
| private fun mapToDto(order: Order): OrderDto { | ||
| return OrderDto(order.orderId!!.id, order.organisationId.id, order.orderAmount.amount) | ||
| } | ||
|
|
||
| private fun mapToDomain(organisationId: UUID, orderRequest: OrderRequest): Order { | ||
| return Order(null, Entity(organisationId), OrderAmount(orderRequest.amount), mutableSetOf()) | ||
| } | ||
|
|
||
| private fun mapToDomain(orderId: UUID, shipmentRequest: ShipmentRequest): Shipment { | ||
| return Shipment(null, OrderId(orderId), ShipmentAmount(shipmentRequest.amount)) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer to use separate domain and dto objects which allow control over what internal domain information is exposed outside domain and it also helps to transform or convert some information at times.
| @Service | ||
| class OrderService(val repository: OrderRepository) { | ||
|
|
||
| @Transactional(readOnly = true) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Order service which offers method to create, fetch orders and notifying shipment for an order
| @@ -0,0 +1,6 @@ | |||
| CREATE TABLE IF NOT EXISTS organisations_schema.shipments | |||
| ( | |||
| id UUID DEFAULT uuid_generate_v4() PRIMARY KEY, | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Intentionally kept the schema simple - just to demonstrate for exercise requirement. Same is applicable to Order table.
This PR is developed as pairing exercise with the aim to implement following business requirement.
Merchant can let the customers pay with Billie payment method, when it happens merchant is not paid straight away. But merchant needs to inform Billie about shipment the product. One order can have multiple products and hence it is possible order is fulfilled by merchant in different shipments. Merchant is only paid when Billie is notified about the shipment amount.
To ensure merchant is not paid more than order amount, shipment amount is summed up and notification attempt is rejected if it violets this rule.
Technically this PR adds few APIs to let merchant application/admin portal sends order request with total order amount, query all the orders belong to it and finally notifies shipment with shipment amount.